home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / tnos / tnos100s / reqsvr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-16  |  12.4 KB  |  484 lines

  1. /* Those who hate GOTOs (like me) B E W A R E............
  2.    To save code space, extensive use of GOTOs was used to prevent
  3.    repetition of code. Could SURELY be cleaner, but it works!
  4.    KO4KS    */
  5.  
  6. #include <stdio.h>
  7. #include <time.h>
  8. #include <dos.h>
  9. #include "config.h"
  10. #include "bm.h"
  11. #include "ftpserv.h"
  12. #include "mailutil.h"
  13. #include "dirutil.h"
  14. #include "files.h"
  15. #include "smtp.h"
  16.  
  17. extern int mailuser __ARGS((FILE *data,char *from,char *to,char *origto));
  18. extern int groupcommand __ARGS((char *action,char *group,char *user,int local, FILE **out, FILE *in));
  19. extern char DAEMONSTR[], Version[];
  20. extern char *skipwhite __ARGS((char *));
  21. extern char *skipnonwhite __ARGS((char *));
  22. extern char *Mbfwdinfo;
  23. extern char shortversion[], SysMessage[];
  24.  
  25. static char DAEMONSTR[] = "%sREQSVR@%s (Mail Delivery Subsystem)\n";
  26.  
  27. int
  28. rdaemon(data, from, to, msg, msgtype, mode)
  29. FILE *data;        /* pointer to rewound data file */
  30. char *from, *to, *msg, msgtype;
  31. int mode;
  32. {
  33. time_t t;
  34. FILE *tfile;
  35. char buf[LINELEN], *newaddr, *orgto;
  36. long mid;
  37.  
  38.     if((tfile = tmpfile()) == NULLFILE)
  39.         return -1;
  40. /*    if (to == NULLCHAR)
  41.         mode = 1;        */
  42.     to = strdup ((to == NULLCHAR) ? "sysop" : to);
  43.         
  44.     orgto = strdup (to);
  45.     if((newaddr = rewrite_address(to)) != NULLCHAR)    {
  46.         free (to);
  47.         to = newaddr;
  48.     }
  49.     time(&t);
  50.     fprintf(tfile,Hdrs[RECEIVED]);
  51.     fprintf(tfile,"from %s ",Hostname);
  52.     mid = get_msgid(0);
  53. #ifdef MBFWD
  54.     fprintf(tfile,"by %s (%s) with SMTP\n\tid AA%ld ; %s",
  55.         Hostname, (Mbfwdinfo != NULLCHAR) ? Mbfwdinfo : shortversion, \
  56.         mid, ptime(&t));
  57. #else
  58.     fprintf(tfile,"by %s (%s) with SMTP\n\tid AA%ld ; %s",
  59.         Hostname, shortversion, mid, ptime(&t));
  60. #endif
  61.     fprintf(tfile,"%s%c\n",Hdrs[BBSTYPE], msgtype);
  62.     fprintf(tfile,"%s%s",Hdrs[DATE],ptime(&t));
  63.     mid = get_msgid(1);
  64.     fprintf(tfile,"%s<%ld@%s>\n",Hdrs[MSGID],mid,Hostname);
  65.     if (from == NULLCHAR)
  66.         fprintf(tfile,DAEMONSTR,Hdrs[FROM],Hostname);
  67.     else
  68.         fprintf(tfile,"%s%s\n",Hdrs[FROM],from);
  69.     fprintf(tfile,"%s%s\n",Hdrs[TO], orgto);
  70.     fprintf(tfile,"%s%s\n\n",Hdrs[SUBJECT], msg);
  71.  
  72.     if (data != NULLFILE)    {
  73.         if (mode)
  74.             fprintf(tfile,"  ===== Message %sfollows ====\n", (msg == SysMessage) ? "" : "header ");
  75.         while(fgets(buf,sizeof(buf),data) != NULLCHAR)    {
  76.             if(mode && buf[0] == '\n')
  77.                 break;
  78.             pwait (NULL);
  79.             fputs(buf,tfile);
  80.         }
  81. /*        if (mode && (msg != SysMessage))
  82.             fprintf(tfile,"  ===== Message Stored ====\n");        */
  83.     } else
  84.         fputc ('\n', tfile);
  85.     rewind(tfile);
  86.  
  87.     sprintf (buf, "REQSVR@%s", Hostname);
  88.     (void) mailuser(tfile, (from) ? from : buf, to, orgto);
  89.     free (to);
  90.     free (orgto);
  91.     fclose(tfile);
  92.     return 0;
  93. }
  94. #if defined(REQSVR) || defined(RMAIL)
  95.  
  96. static void
  97. parseheader (fp, from, subject, buf, startat)
  98. FILE *fp;
  99. char *from, *subject, *buf;
  100. long *startat;
  101. {
  102. char *cp, *temp;
  103.  
  104.     rewind (fp);
  105.     subject[0] = from[0] = 0;
  106.     while(fgets(buf,128,fp) != NULLCHAR)    {
  107.         if(buf[0] == '\n')
  108.             break;
  109.         rip (buf);
  110.         if (htype(buf) == FROM)        {
  111.             cp = &buf[strlen(Hdrs[FROM])];
  112.             if (*cp == '"')    {
  113.                 cp++;
  114.                 if ((temp = strchr (cp, '"')) != NULLCHAR)
  115.                     cp = temp+1;
  116.             }
  117.             if ((temp = strchr (cp, '<')) != NULLCHAR)    {
  118.                 cp = temp+1;
  119.                 if ((temp = strchr (cp, '>')) != NULLCHAR)
  120.                     *temp = 0;
  121.             }
  122.             if ((temp = strpbrk (cp, " \t")) != NULLCHAR)
  123.                 *temp = 0;
  124.             strcpy (from, cp);
  125.         }
  126.         if (htype(buf) == SUBJECT)    {
  127.             cp = &buf[strlen(Hdrs[SUBJECT])];
  128.             cp = skipwhite(cp);
  129.             if (*cp == '"')    {
  130.                 cp++;
  131.                 if ((temp = strchr (cp, '"')) != NULLCHAR)
  132.                     *temp = 0;
  133.             }
  134.             strcpy (subject, cp);
  135.         }
  136.     }
  137.     *startat = ftell (fp);
  138.     if (fgets(buf,128,fp) != NULLCHAR)    {
  139.         if(!strnicmp (buf, "R:", 2))    {
  140.             while(fgets(buf,128,fp) != NULLCHAR)    {
  141.                 if(buf[0] == '\n')
  142.                     break;
  143.             }
  144.         *startat = ftell (fp);
  145.         }
  146.     }
  147.     pwait (NULL);
  148. }
  149.  
  150.  
  151. static int
  152. handleError (fp, from, str)
  153. FILE *fp;
  154. char *from, *str;
  155. {
  156.     rewind (fp);
  157.     rdaemon (fp, NULLCHAR, from, str, 'P', 1);
  158.     rewind (fp);
  159.     rdaemon (fp, NULLCHAR, NULLCHAR, str, 'P', 1);
  160.     return 0;    /* pass the message back */
  161. }
  162.  
  163.  
  164. #endif
  165.  
  166.  
  167. #ifdef RMAIL
  168. static char rmailerror[] = "Rmail Error";
  169.  
  170. static void
  171. rmailit (fp, from, to, subject, startat)
  172. FILE *fp;
  173. char *from, *to, *subject;
  174. long startat;
  175. {
  176. char *thisto;
  177.  
  178.     while (*to && to)    {
  179.         thisto = to;
  180.         to = strchr (to, ',');
  181.         if (to)    {
  182.             *to++ = 0;
  183.             to = skipwhite (to);
  184.         }
  185.         if (!strnicmp (thisto, "rmail@", 6))
  186.             continue;
  187.         pwait (NULL);
  188.         fseek (fp, startat, SEEK_SET);
  189.         rdaemon (fp, from, thisto, subject, 'P', 0);
  190.     }
  191. }
  192.  
  193.  
  194. int
  195. rmail (fp, from)
  196. FILE *fp;
  197. char *from;
  198. {
  199. char buf[512], subject[256], realfrom[128], *to = NULLCHAR;
  200. long startat;
  201.  
  202.     parseheader (fp, realfrom, subject, buf, &startat);
  203.     if (realfrom[0] && subject[0])        {
  204.         while(fgets(buf,512,fp) != NULLCHAR)    {
  205.             if(buf[0] == '\n')
  206.                 break;
  207.             if (htype(buf) == TO)    {
  208.                 if (to != NULLCHAR)    {    /* more than 1 To: - ERROR */
  209.                     free (to);
  210.                     to = NULLCHAR;
  211.                     break;
  212.                 } else    {
  213.                     rip(buf);
  214.                     to = strdup (&buf[4]);
  215.                 }
  216.             }
  217.         }
  218.         if (to != NULLCHAR)    {
  219.             rmailit (fp, realfrom, to, subject, startat);
  220.             free (to);
  221.             return 1;
  222.         }
  223.     }
  224.     return (handleError (fp, realfrom, rmailerror));
  225. }
  226.  
  227. #endif
  228.  
  229.  
  230.  
  231. #ifdef REQSVR
  232. int
  233. reqsvr (fp, from)
  234. FILE *fp;
  235. char *from;
  236. {
  237. char buf[128];
  238. char name[128], path[128], realfrom[128];
  239. char subject[LINELEN], *file, cmd, *cp = path, action = 'I', *ptr, *ptr2;
  240. int anony = 1, mode = RETR_CMD, found = 0, first = 0;
  241. FILE *out, *out2;
  242. long prev, msgdata, privs;
  243. unsigned attr;
  244. int err;
  245.  
  246.     parseheader (fp, realfrom, subject, buf, &prev);
  247.     sprintf(buf,"%s/reqsvr.log",Spool);
  248.     if((out = fopen(buf,APPEND_TEXT)) != NULLFILE)    {
  249.         time_t t;
  250.         time(&t);
  251.         fprintf (out, "Received from %s (%s) on %s", realfrom, subject, ptime(&t));
  252.         fclose (out);
  253.     }
  254.     if (!*subject)
  255.         return 0;    /* we are konfuzd! No subject!?!? */
  256.     pwait (NULL);
  257.     do    {
  258.         if (fgets(buf,128,fp) == NULLCHAR)
  259.             break;
  260.         if (!first && *buf == '\n')
  261.             strcpy (buf, "R:");
  262.         if (!strnicmp (buf, "R:", 2))
  263.             found = 1;
  264.         first = 1;
  265.     } while (*buf != '\n');
  266.     if (!found)
  267.         fseek (fp, prev, SEEK_SET);
  268. /*    else
  269.         fgets(buf,128,fp);    */    /* strip off blank line */
  270.  
  271.     /* now the fix for FBB/PRMBS/TNOS adding RFC 822-type lines to messages */
  272.     prev = ftell (fp);
  273.     if (fgets (buf, 128, fp) != NULLCHAR)    {
  274.         if (strnicmp (buf, "From:", 5) && strnicmp (buf, "Date:", 5) && strnicmp (buf, "Message-Id:", 11))
  275.             fseek (fp, prev, SEEK_SET);
  276.         else    do    {
  277.                 if (fgets (buf, 128,fp) == NULLCHAR)
  278.                     break;
  279.             } while (*buf != '\n');
  280.     }
  281.  
  282.     msgdata = ftell (fp);
  283.     strncpy (name, realfrom, 40);
  284.     file = strchr (name, '@');
  285.     if (file)
  286.         *file = 0;
  287.     cmd = tolower (*subject);
  288.     /* get senders permissions and default path */
  289.     privs = userlogin (name, NULLCHAR, &cp, 128, &anony);
  290.     
  291.     file = skipnonwhite (&subject[1]);
  292.     file = skipwhite (file);
  293.     file = pathname (path, file);
  294.     _dos_getfileattr (file, &attr);
  295.     if (!strnicmp (subject, "infor", 5))
  296.         cmd = 'f';    /* inform */
  297.     if (!strnicmp (subject, "uni", 3))
  298.         cmd = 'n';    /* uninform */
  299.     if (!strnicmp (subject, "uns", 3))
  300.         cmd = 'c';    /* unsubscribe */
  301.  
  302.     switch (cmd)    {
  303.         case 'i':    /* info */
  304.         case 'h':    /* help */
  305.                 free (file);
  306.                 file = pathname (Helpdir, "reqsvr.hlp");
  307.                 if ((out = fopen (file, READ_TEXT)) != NULLFILE)
  308.                     goto okay;
  309.                 sprintf (buf, "Not Found %s", subject);
  310.                 goto error;
  311.         case 'g':    /* group commands */
  312.                 ptr = skipnonwhite (&subject[1]);
  313.                 ptr = skipwhite (ptr);
  314.                 cmd = tolower (*ptr);
  315.                 if (cmd != 's' && cmd != 'u' && cmd != 'l')
  316.                     if (privs == -1 || !(privs & SYSOP_CMD))
  317.                         goto denied;
  318.  
  319.                 ptr2 = skipnonwhite (ptr);
  320.                 action = *ptr2;
  321.                 *ptr2++ = 0;
  322.                 ptr2 = skipwhite (ptr2);
  323.                 switch (cmd)    {
  324.                     case 's':
  325.                     case 'u':
  326.                     case 'a':
  327.                     case 'd':
  328.                     case 'i':
  329.                     case 'l':    out = NULLFILE;
  330.                             found = groupcommand (ptr, (action) ? ptr2 : NULLCHAR, realfrom, 0, &out, fp);
  331.                             *(--ptr2) = action;
  332.                             if (found)    {
  333.                                 if (cmd == 'l')
  334.                                     goto done;
  335.                                 else
  336.                                     goto okay;
  337.                             } else
  338.                                 goto denied;
  339.                     default:    *(--ptr2) = action;
  340.                             goto confuzed;
  341.                 }
  342.         case 'q':    /* return callbook server data */
  343. #ifdef SAMCALLB
  344.                 ptr = skipnonwhite (&subject[1]);
  345.                 ptr = skipwhite (ptr);
  346.                 if((out = tmpfile()) != NULLFILE){
  347.                     if ((err = cb_lookup (0, ptr, out)) != 0)    {
  348.                         if (err == 1)
  349.                             goto confuzed;
  350.                         else
  351.                             fprintf (out, "Amateur callsign '%s' not found or invalid\n", ptr);
  352.                     }
  353.                     goto okay;
  354.                 }
  355. #endif
  356.                 goto ioerror;
  357.         case 'v':    /* return version info */
  358.                 if((out = tmpfile()) != NULLFILE){
  359.                     fprintf (out, "Currently running %s at %s\n", Version, Hostname);
  360.                     goto okay;
  361.                 }
  362.                 goto ioerror;
  363.         case 'u':    /* upload a file */
  364.                 mode = STOR_CMD;
  365.         case 's':    /* subscribe to a file */
  366.         case 'c':    /* unsubscribe to a file */
  367.         case 'f':    /* inform of changes to a file */
  368.         case 'n':    /* uninform of changes to a file */
  369.         case 'w':    /* send a directory */
  370.         case 'd':    /* download a file */
  371.                 if ((privs == -1) || (!permcheck(path, privs, mode, file)))    {
  372. denied:                    sprintf (buf, "Denied %s", subject);
  373.                     goto error;
  374.                 }
  375.                 switch (cmd)    {
  376.                     case 'c':    /* unsubscribe */
  377.                     case 'n':    /* uninform */
  378.                     case 's':    /* subscribe */
  379.                     case 'f':    /* inform */
  380.                         if (cmd == 'c' || cmd == 's')    /* subscribe functions */
  381.                             action = 'S';
  382.                         if(attr & FA_DIREC)    /* whole dir */
  383.                             cp = "/";
  384.                         else    {
  385.                             cp = strrchr (file, '/');
  386.                             *cp++ = 0;
  387.                         }
  388.                         sprintf(buf,"%s/reqsvr.dat",file);
  389.                         if (cmd == 's' || cmd == 'f')    {    /* adding functions */
  390.                             if((out = fopen(buf,APPEND_TEXT)) != NULLFILE)    {
  391.                                 fprintf (out, "%s %s %c\n", cp, realfrom, action);
  392.                                 goto complete;
  393.                             }
  394.                             goto ioerror;
  395.                         } else    {        /* removing functions */
  396.                             if((out = fopen(buf,UPDATE_TEXT)) != NULLFILE)    {
  397.                                 while(fgets(buf,128,out) != NULLCHAR)    {
  398.                                     pwait (NULL);
  399.                                     rip (buf);
  400.                                     if (!strnicmp (buf, cp, strlen (cp)))
  401.                                         if (!strnicmp ((strchr (buf, ' ') + 1), realfrom, strlen (realfrom)))
  402.                                             if (buf[strlen(buf) - 1] == action)    {
  403.                                                 fseek (out, (long) (ftell (out) - 3), SEEK_SET);
  404.                                                 fputc ('N', out);
  405.                                                 break;
  406.                                             }
  407.                                 }
  408.                             }
  409.                             goto complete;
  410.                         }
  411.                     case 'w':    /* what (dir) */
  412.                         if((out = dir(file, 1)) == NULLFILE)
  413.                             goto ioerror;
  414.                         goto okay;
  415.                     case 'u':    /* upload */
  416.                         if ((out = fopen (file, WRITE_TEXT)) == NULLFILE)    {
  417. ioerror:                        sprintf (buf, "IO Error %s", subject);
  418.                             goto error;
  419.                         }
  420.                         while(fgets(buf,128,fp) != NULLCHAR)    {
  421.                             pwait (NULL);
  422.                             fputs(buf,out);
  423.                         }
  424.                         fclose (out);
  425.                         cp = strrchr (file, '/');
  426.                         *cp++ = 0;
  427.                         sprintf(buf,"%s/reqsvr.dat",file);
  428.                         if((out = fopen(buf,READ_TEXT)) != NULLFILE)    {
  429.                             if((out2 = tmpfile()) != NULLFILE)
  430.                                 fprintf (out2, "File changed by %s\n", realfrom);
  431.                             while(fgets(name,128,out) != NULLCHAR)    {
  432.                                 pwait (NULL);
  433.                                 if (*name == '/' || !strnicmp (name, cp, strlen (cp)))    {
  434.                                     ptr = strrchr (name, ' ');
  435.                                     *ptr = 0;
  436.                                     action = ptr[1];
  437.                                     ptr = (strchr (name, ' ') + 1);
  438.                                     switch (action)    {
  439.                                          case 'S':
  440.                                              sprintf (buf, "Subscribe %s/%s", file, cp);
  441.                                              fseek (fp, msgdata, SEEK_SET);
  442.                                              rdaemon (fp, NULLCHAR, ptr, buf, 'P', 0);
  443.                                              break;
  444.                                          case 'I':
  445.                                              sprintf (buf, "Inform %s/%s", file, cp);
  446.                                             if (out2 != NULLFILE)
  447.                                                 rewind (out2);
  448.                                              rdaemon (out2, NULLCHAR, ptr, buf, 'P', 0);
  449.                                              break;
  450.                                     }
  451.                                 }
  452.                             }
  453.                             if (out2 != NULLFILE)
  454.                                 fclose (out2);
  455.                         }
  456. complete:                    if (out != NULLFILE)    {
  457.                             fclose (out);
  458.                             out = NULLFILE;
  459.                         }
  460.                         goto okay;
  461.                     case 'd':    /* download */
  462.                         if ((out = fopen (file, READ_TEXT)) == NULLFILE)
  463.                             goto ioerror;
  464. okay:                        sprintf (buf, "Accepted %s", subject);
  465.                         if (out != NULLFILE)
  466.                             rewind (out);
  467.                         rdaemon (out, NULLCHAR, realfrom, buf, 'P', 0);
  468.                         if (out != NULLFILE)
  469.                             fclose (out);
  470.                 }
  471.                 break;
  472. confuzed:
  473.         default:    sprintf (buf, "Unknown %s", subject);
  474.                 goto error;
  475.     }
  476. done:    free (file);
  477.     return 1;    /* we handled it, here! */
  478.  
  479. error:    free (file);
  480.     return (handleError (fp, realfrom, buf));
  481. }
  482.  
  483. #endif
  484.